package com.xx.questionnaire.util.dao;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp2.BasicDataSourceFactory;
import org.apache.log4j.Logger;

/**
 * @version 0.1
 * @author Administrator
 * 
 */
public class Dbcp_connection implements JdbcI {
	static Logger log = Logger.getLogger(Dbcp_connection.class);
	private Connection connection;
	/**
	 * 在静态块中初始化获得DBCP数据源连接池
	 */
	static {
		getDataSource();
		log.info("数据源已在静态块中初始化完成。");
	}

	/**
	 *@return 返回Connection连接
	 */
	public Connection getConnection() {
		if (connection == null || connection.equals("")) {
			try {
				setConnection(getDataSource().getConnection());
				log.info("从数据源中获取连接！");
				return connection;
			} catch (SQLException e) {
				log.error("对不起，数据库连接获取失败！");
				e.printStackTrace();
			}
		}
		return null;
	}
	/**
	 * @param sql	SQL语句
	 * @return PrepaedStatement对象
	 */
	public PreparedStatement getPStatement(String sql) {
		if (sql == null || sql.equals("")) {
			log.error("错误，SQL语句不允许为空!");
			return null;
		}
		PreparedStatement ps = null;
		try {
			ps = getConnection().prepareStatement(sql);
			log.info("SQL语句" + sql + "已经过预编译！");
			return ps;
		} catch (SQLException e) {
			log.error("异常，SQL语句" + sql + "预编译失败！");
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * 强制释放Connection连接。
	 * 
	 */
	public void close() {
		try {
			this.connection.close();
			log.info("Connection object" + this.connection.hashCode()
					+ "被强制释放！");
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	 
	public void close(Statement ps) {
		// TODO Auto-generated method stub
		try {
		 
			ps.close();
			this.connection.close();
			log.info("Statement（"
					+ ps.hashCode() + "），Connection("
					+ this.connection.hashCode() + ")已被释放！");
		} catch (SQLException e) {
			log.error("异常，JDBC对象关闭失败！");
			e.printStackTrace();
		}
		
	}
	/**
	 * 按照顺序释放JDBC连接。
	 */
	public void close(Statement ps, ResultSet rs) {
		// TODO Auto-generated method stub
		try {
			rs.close();
			ps.close();
			this.connection.close();
			log.info("ResultSet（" + rs.hashCode() + "），Statement（"
					+ ps.hashCode() + "），Connection("
					+ this.connection.hashCode() + ")已被释放！");
		} catch (SQLException e) {
			log.error("异常，JDBC对象关闭失败！");
			e.printStackTrace();
		}

	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		/* 1 */
		DataSource dds = getDataSource();
		System.out.println(dds == null ? "数据源失败" : "数据源成功");

	}

	/**
	 * 全局公用的数据源
	 * 
	 * @return DataSource Object
	 */
	private static DataSource getDataSource() {
		String dbcpUrl = "dbcp-mysql.properties";

		DataSource ds;
		Properties p = new Properties();
		try {
			// 通过类的类加载器将属性文件加载至输入流
			p.load(JDBCUtil.class.getClassLoader().getResourceAsStream(dbcpUrl));
			log.info("DBCP配置文件已加载！");

			ds = BasicDataSourceFactory.createDataSource(p);
			log.info("数据源获取成功！");
			return ds;

		} catch (IOException e) {
			log.error("异常，可能是配置文件读取失败。");
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	private void setConnection(Connection connection) {
		log.info("获取连接，Hash地址为：" + connection.hashCode());
		this.connection = connection;
	}

	public DataSource getDS() {
		// TODO Auto-generated method stub
		log.info("数据源被外部调用！");
		return getDataSource();
	}

}
